<?php
/**
 * Created by PhpStorm.
 * User: 小蛮哼哼哼
 * Email: 243194993@qq.com
 * Date: 2022/5/7
 * Time: 15:26
 * motto: 现在的努力是为了小时候吹过的牛逼！
 */

namespace app\pay\controller;

use app\admin\controller\weixin\ExpressOrder;
use app\BaseController;
use app\common\lib\ArrClass;
use app\common\lib\Http;
use app\common\lib\Show;
use app\common\lib\Status;
use app\common\model\MallOrder;
use app\common\model\MallOrderGoods;
use app\common\model\MallShop;
use app\common\model\PointReceive;
use app\common\model\PointSource;
use app\common\model\WeixinExpress;
use app\common\model\WeixinExpressOrder;
use app\common\model\WeixinExpressOrderList;
use EasyWeChat\Factory;
use Htlove\Str;
use think\App;
use think\facade\Cache;
use think\facade\Log;

class Notify extends BaseController
{
    protected $wechat_app = null;
    protected $mini_app = null;

    public function __construct(App $app)
    {
        $config = [
            'app_id' => sysconfig('weixin', 'wx_mini_app_id'),
            'mch_id' => sysconfig('weixin', 'wx_pay_mch_id'),
            'key' => sysconfig('weixin', 'wx_pay_key'),   // API 密钥

            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path' => public_path() . sysconfig('weixin', 'wx_pay_cert'), // XXX: 绝对路径！！！！
            'key_path' => public_path() . sysconfig('weixin', 'wx_pay_cert_key'),      // XXX: 绝对路径！！！！
        ];
        $this->wechat_app = Factory::payment($config);
        $this->mini_app = Factory::miniProgram([
            "app_id" => sysconfig('weixin', "wx_mini_app_id"),
            "secret" => sysconfig('weixin', 'wx_mini_secret_id'),
            'response_type' => 'array',
            'log' => [
                'level' => 'debug',
                'file' => runtime_path('easywechat') . 'wechat.log',
            ],
        ]);
        parent::__construct($app);
    }

    /**
     * 普通支付
     * @return void
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
    public function index()
    {
        Log::info("====================收到支付通知====================");
        $response = $this->wechat_app->handlePaidNotify(function ($message, $fail) {
            // 修改订单状态 修改库存 销量
            Log::info("收到支付通知参数:" . Show::json_encode($message));
            Log::info("====================开始处理订单====================");
            $obj_order = new MallOrder();
            $order = $obj_order->getOrderByOrderId($message['out_trade_no']);
            if (!$order || $order['status'] != 0) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
            $update_data = [];
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
                    $rrr = $this->mini_app->access_token->getToken();
                    //发送模板消息
                    $params = array(
                        'touser' => $order['openid'],
                        'template_id' => "cGnM4-OWU4wbRP7bTRMyoDH1GSvBaFysOQR3FTzD2ao",
                        'page' => 'pages/index/index',
                        'data' => [
                            "character_string2" => [
                                "value" => $order['ordersn']
                            ],
                            "amount1" => [
                                "value" => $order['payprice']
                            ],
                            "date3" => [
                                "value" => $order['create_time']
                            ],
                            "thing7" => [
                                "value" => "感谢您选购"
                            ],
                        ]
                    );
                    $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $rrr['access_token'];
                    $res = Http::post($url, json_encode($params));
                    $update_data['paytime'] = time();
                    $update_data['status'] = 1;
                    $update_data['transaction_id'] = $message['transaction_id'];
                    $obj_order->startTrans();
                    try {
                        //更新数据
                        $obj_order->updateDataSave($order['id'], $update_data);
                        //增加积分
                        $point = (new PointSource())->setPontSourceByData();
                        $point_number = $order['payprice'] / $point['aps_trade'];
                        $insert_data = [
                            "number" => intval($point_number),
                            "order_id" => $message['out_trade_no'],
                            "type" => 1,
                            "openid" => $order['openid']
                        ];
                        (new PointReceive())->insertSaveById($insert_data);
                        //增加销量 todo  查询订单商品 然后更新商品销量
                        (new MallOrderGoods())->setOrderGoodsBySale($order['id']);
                        //查看是否有打印机
                        if ($order['is_express'] == 1) {
                            Log::info("====================需要处理快递====================");
                            $this->setExpress($order['id']);
                        }
                        //打印订单
                        $this->sendprint($message['out_trade_no']);
                        $obj_order->commit();
                    } catch (\Exception $e) {
                        Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                        Log::info("====================订单处理异常====================");
                        $obj_order->rollback();
                        return $fail("处理异常");
                    }
                    return true;
                } else if ($message['result_code'] === 'FAIL') {
                    //支付失败
                    return true;
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
            return true;
        });

        $response->send();
    }

    /**
     * @param int $order_id
     * @return string|void
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function setExpress(int $order_id = 0)
    {
        $order = (new WeixinExpressOrder())->getOrderByOrderSnByInfo($order_id);
        Log::info("====================查询到快递====================");
        if (!$order) {
            Log::info("====================没有快递{$order_id}====================");
            return "success";
        }
        $order = $order->toArray();
        Log::info("====================开始减少====================");
        (new WeixinExpressOrder())->updateDataSave($order['id'], [
            "pay_status" => 1,
            "update_time" => time()
        ]);
        (new WeixinExpress())->save([
            "num" => "-" . $order['express_number'],
            "openid" => $order['openid']
        ]);
    }

    /**
     * @param string $order_id
     * @param $type
     * @return void
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function sendprint(string $order_id = "", $type = 1)
    {
        if ($type == 1) {
            $row = (new MallOrder())->getOrderByOrderId($order_id);
            $goods_list = (new MallOrderGoods())->getOrderGoodsByOrderIdAll($row['id'], 'goods');
        } else {
            $row = (new WeixinExpressOrder())->getExpressByOrderIdByInfo($order_id);
            if ($row) {
                $row = $row->toArray();
            } else {
                $row = [];
            }
            $row['is_express'] = 1;
            $goods_list = [];
        }
        Log::info("查询到商品:" . Show::json_encode($row));

        //查询店铺
        $shop = (new MallShop())->getBaseById($row['shop_id']);
        if (empty($shop['id'])) {
            $shop['id'] = '123';
        }
        $key = "printer_key_value_" . date('Y-m-d') . $shop['id'];
        $number = Cache::get($key);
        if (!$number) {
            $number = 1;
        }

        //dump($shop);exit();
        $guid = \app\common\lib\Str::guid();
        $content = "<FS2><center>驿点生活 - {$shop['title']}</center></FS2>";
        $content .= str_repeat('.', 32);
        if ($type == 1) {
            $content .= "联系人:" . $row['realname'] . " \n";
            $content .= "收货人电话:" . $row['mobile'] . " \n";
            $content .= "收货地址:" . $row['address'] . " \n";
            $content .= "下单时间:" . $row['create_time'] . "\n";
            $content .= "订单编号:" . $row['ordersn'] . "\n";
            $content .= "备注:" . $row['remark'] . "\n";
            $content .= "订单总价:￥" . $row['payprice'] . " \n";
            //判断是那个店铺
        } else {
            $content .= "联系人:" . $row['realname'] . " \n";
            $content .= "收货人电话:" . $row['mobile'] . " \n";
            $content .= "收货地址:" . $row['address'] . " \n";
            $content .= "下单时间:" . $row['create_time'] . "\n";
            $content .= "备注:" . $row['description'] . "\n";

        }


        //获取快递单号
        if ($row['is_express'] == 1 || $type == 2) {
            $content .= str_repeat('*', 14) . "快递" . str_repeat("*", 14);
            //有快递
            if ($type == 1) {
                $express = (new WeixinExpressOrder())->getExpressByOrderId($row['id']);
            } else {
                $express = (new WeixinExpressOrderList())->getExpressByOrderId($row['id']);
            }
            if ($express) {
                $content .= "<table>";
                $content .= "<tr><td>快递取件码</td></tr>";
                foreach ($express as $v) {
                    $content .= "<tr><td>{$v['express']}</td></tr>";
                }
                $content .= "</table>";
                $content .= "快递数量:x" . count($express) . "\n";
                if ($type == 1) {
                    $content .= "快递金额:0" . "\n";
                } else {
                    $content .= "快递金额:" . $row['price'] . "\n";
                }
                $content .= str_repeat('*', 32);
            }
        }
        if ($type == 1) {
            $content .= str_repeat('*', 14) . "商品" . str_repeat("*", 14);
            $content .= "<table>";
            $content .= "<tr><td>名称</td><td>数量</td><td>金额</td></tr>";
            foreach ($goods_list as $k => $v) {
                $content .= "<tr>";
                $content .= "<td>" . $v['goods_name'] . "</td><td>x" . $v['total'] . "</td><td>" . $v['price'] . "</td>";
                $content .= '</tr>';
            }
            $content .= "</table>";
            $content .= str_repeat('.', 32);
            $content .= "小计:￥" . $row['orderprice'] . "\n";
            $content .= "折扣:￥" . $row['discountprice'] . " \n";
        }
        $content .= str_repeat('*', 32);


        $url = request()->domain() . "/qrcode";
//        dump($url);exit();
        $content .= "<QR>{$url}</QR>" . PHP_EOL;


        //$content .= "<FS2><center>**#{$number} 完**</center></FS2>";
        $content .= "收藏”驿点生活小程序“" . "\n";
        $content .= "快递包裹/严选好物，替你送上门" . "\n";
        $content .= "客服电话：19112247033" . "\n";

        Cache::set($key, $number + 1, 86400);
        if ($type == 1) {
            $send_data = [
                'machineCode' => $shop['express_id'],
                'content' => $content,
                'type' => 1,
                'id' => $guid,
                'openid' => $row['openid']
            ];
            $send_data1 = [
                'machineCode' => $shop['machine_id'],
                'content' => $content,
                'type' => 1,
                'id' => $guid,
                'openid' => $row['openid']
            ];

            Log::info("打印机器的记录：" . Show::json_encode($send_data));
            $this->sendPrinter($send_data);
            $this->sendPrinter($send_data1);

        } else if ($type == 2) {
            $send_data = [
                'machineCode' => $shop['machine_id'],
                'content' => $content,
                'type' => 1,
                'id' => $guid,
                'openid' => $row['openid']
            ];
            if ($type == 2) {
                $send_data['machineCode'] = $shop['express_id'];
            }

            Log::info("打印机器的记录：" . Show::json_encode($send_data));
            $this->sendPrinter($send_data);
        }
        $send_data2 = [
            'machineCode' => sysconfig('shop', 'order_machine'),
            'content' => $content,
            'type' => 1,
            'id' => $guid,
            'openid' => $row['openid']
        ];
        $this->sendPrinter($send_data2);
    }

    protected function sendPrinter(array $send_data = [])
    {
        try {
            $obj = ArrClass::initClass(sysconfig('printer', 'print_type'), ArrClass::printer(), [["clientId" => sysconfig('printer', 'client_id'), "clientSecret" => sysconfig('printer', 'client_secret')]], true);
            $result = $obj->printer($send_data);
        } catch (\Exception $e) {
            Log::error("发送订单信息错误:" . $e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
            return "success";
        }
        return $obj;
    }

    public function express()
    {
        Log::info("====================收到快递支付通知====================");
        $response = $this->wechat_app->handlePaidNotify(function ($message, $fail) {

            // 修改订单状态 修改库存 销量
            Log::info("收到支付通知参数:" . Show::json_encode($message));
            Log::info("====================开始处理订单====================");
            $obj_order = new WeixinExpressOrder();
            $order = $obj_order->getExpressByOrderIdByInfo($message['out_trade_no']);
            if (!$order || $order['pay_status'] != 0) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
            $update_data = [];
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
                    //进行订单状态修改
                    $update_data = [
                        "pay_status" => 1,
                        "update_time" => time()
                    ];
                    $obj_order->updateDataSave($order['id'], $update_data);
                    //减少快递次数
                    if ($order['express_number'] > 0) {
                        (new WeixinExpress())->insert([
                            "num" => "-" . $order['express_number'],
                            "openid" => $order['openid']
                        ]);
                    }
                    //打印快递
                    $this->sendprint($order['order_id'], 2);
                }
            }
            return true;
        });
        $response->send();
    }
}